package com.xiaotu.spider.mgtv.pageprocessor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.TVDanMuCommentModel;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.HtmlUtil;
import com.xiaotu.common.util.HttpUtils;
import com.xiaotu.common.util.KeywordEncode;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.common.util.StringUtil;
import com.xiaotu.spider.APageProcessor;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

/**
 * 爬取芒果TV网大电影弹幕
 * @author wangyanlong
 * @date 2019年8月6日 上午10:54:47
 *
 */
@Component("MGMovieDanMuPageProcessor")
@Scope("prototype")
public class MGMovieDanMuPageProcessor extends APageProcessor
{
	private String requRL = "http://galaxy.bz.mgtv.com/rdbarrage?vid=%s&cid=%s&time=%s&platform=0";
	
    @Override
    protected Request getStartRequest(JSONObject target)
    {
        return new Request("https://so.mgtv.com/so/k-"+KeywordEncode.encode(target.getString("tvName")));
    }

    @Override
    public void process(Page page)
    {
        Map<String, Object> tvMap = page.getRequest().getExtras();
        switch (this.getPageDataType(page))
        {
            case Constants.PageDataType.SEARCH_LIST:
                this.searchListProcess(page, tvMap);
                break;
            case Constants.PageDataType.BASICINFO:
                this.tvDetailList(page,tvMap);
                break;
            case Constants.PageDataType.TV_RECORD:
                this.tvProcess(page,tvMap);
                break;
            default:
                break;
        }
    }

    private void searchListProcess(Page page, Map<String, Object> tvMap){
    	List<String> divList = page.getHtml()
                .xpath("//div[@class='search-resultlist']/div[@class='so-result-info']")
                .all();
        if (divList == null || divList.isEmpty())
            throw new SpiderException(
                    SpiderExceptionCode.DataInvalideException);
        
        for (String divStr : divList){
            Html divObj = new Html(divStr);
            String  yugaop = divObj.xpath("//p[@class='result-pic']//a//span[@class='info']/text()").get(); //预告片
            if(yugaop !=null && yugaop.equals("预告")){
            	continue;
            }
            
            String tvName = divObj.xpath("//p[@class='result-til']//a").get();
            tvName = StringUtils.isEmpty(tvName) ? divObj.xpath("//div[@class='tele_hd']/a[1]").get() :tvName;
            if(StringUtil.isNotEmpty(tvName)){
            	tvName = RegexUtils.regexChStr(StringUtils.trim(HtmlUtil.delHTMLTag(tvName)));
            }
            boolean dirFlage = false;
            boolean actorFlage = false;
            List<String> pList = divObj.xpath("//p[@class='text-1']/span").all();
            String actors = this.getTVAttr(pList, "主演");
            actors = StringUtils.isEmpty(actors) ? StringUtils.join(divObj.xpath
                    ("//div[@class='info_item'][1]//a/text()").all(), SepratorUtil.SEP_COMMA_EN) :
                    actors;
	        if(StringUtil.isNotEmpty(actors)){
	        	String [] actorArr =actors.split(",");
	        	for (String actor : actorArr) {
	        		if(tvMap.get("actor").toString().contains(actor)){
						actorFlage =true;
						break;
					}
	        	}
	        	
	        }
	        String directors = this.getTVAttr(pList, "导演");
            directors = StringUtils.isEmpty(directors) ? StringUtils.join(divObj.xpath
                    ("//div[@class='info_item'][2]//a/text()").all(), SepratorUtil.SEP_COMMA_EN) :
                    directors;
            if(StringUtil.isNotEmpty(directors)){
            	String[] directorArr = directors.split(",");
            	for (String director : directorArr) {
            		if(tvMap.get("director").toString().contains(director)){
						dirFlage =true;
						break;
					}
				}
            }
            String tvType = this.getTVType(divObj, pList);
            String link = divObj.xpath("//div[@class='result-content clearfix']//div[@class='result-box']//a[1]/@href").get();
            if(StringUtil.isEmpty(link)){
            	break;
            }
            
            String tvOldName = tvMap.get("tvName")+"";
            if(StringUtil.isNotEmpty(tvOldName)){
            	tvOldName = RegexUtils.regexChStr(tvOldName).trim();
            }
            if(tvOldName.equals(tvName) 
            		&& tvMap.get("tvType").toString().equals(tvType) 
            		&& dirFlage && actorFlage && link.contains("www.mgtv.com")){
            	 PageUtils.addTargetRequest(page, link, tvMap);
            }
    	}
    }

    private void tvDetailList(Page page, Map<String, Object> tvMap) {
    	String url = page.getUrl().toString();
    	String cid = url.substring(url.indexOf("b/")+2, url.lastIndexOf("/"));
    	String vid = url.substring(url.lastIndexOf("/")+1, url.indexOf(".html"));
		String link = String.format(requRL,vid,cid,"5000");
		PageUtils.addTargetRequest(page,link,tvMap);
    }
    
    private void tvProcess(Page page, Map<String, Object> tvMap) {
    	String url = page.getUrl().toString();
    	String vid = url.substring(url.indexOf("vid=")+4,url.indexOf("&cid"));
    	String cid = url.substring(url.indexOf("cid=")+4,url.indexOf("&time"));
    	List<TVDanMuCommentModel> resList = new ArrayList<TVDanMuCommentModel>();
    	String time ="5000";
		while(true){
			String httpDanMuJSONP = HttpUtils.httpGetJSONPUTF(String.format(requRL,vid,cid,time));
			if (StringUtil.isEmpty(httpDanMuJSONP))
				throw new SpiderException(
						SpiderExceptionCode.DataInvalideException);
			
			JSONObject searchJson = JSONObject.fromObject(httpDanMuJSONP);
			String datas = searchJson.getJSONObject("data").toString();
			if(StringUtil.isEmpty(datas)){
				break;
			}
			String next = searchJson.getJSONObject("data").getString("next");
			String items = searchJson.getJSONObject("data").getString("items");
			if(StringUtil.isNotEmpty(items)){
				JSONArray comentList = searchJson.getJSONObject("data").getJSONArray("items");
				for (Object coments : comentList) {
					JSONObject comment = JSONObject.fromObject(coments);
					String content = comment.getString("content");
					if(StringUtil.isNotEmpty(content)){
						content = content.replaceAll("[^(0-9a-zA-Z\u4e00-\u9fa5\\p{P}\r\n )]","");
					}
					String up="";
					if(comment.containsKey("up")){
						up = comment.getString("up");
					}else{
						up = "";
					}
					/* page.putField(TVDanMuCommentModel.class.getName(),new TVDanMuCommentModel(tvMap.get("tvid")+"", tvMap.get("tvName")+"",
								comment.getString("id"),"",content,"",comment.getString("time"),
								up,"芒果TV"));*/
					resList.add(new TVDanMuCommentModel(tvMap.get("tvName")+"",
							comment.getString("id"),"",content,"",comment.getString("time"),
							up,"芒果TV")); 
				}
					time = next;
			}else{
				break;
			}
		}
				page.putField(TVDanMuCommentModel.class.getName(), resList);
    }
    /**
     * 获取电视剧的属性
     *
     * @param pList 页面元素类别
     * @param label 属性标识，如：导演、主演
     * @return 属性值
     */
    private String getTVAttr(List<String> pList, String label)
    {
        if (pList == null || pList.isEmpty())
            return null;
        for (String pStr : pList)
        {
            if (!pStr.contains(label))
                continue;
            return StringUtils.join(new Html(pStr).xpath("//a/text()").all(),
                    SepratorUtil.SEP_COMMA_EN);
        }
        return null;
    }
    
    /**
     * 获取作品类型
     *
     * @param divObj 页面元素
     * @param pList  属性元素类别
     * @return 作品类型：如电视剧、电影
     */
    private String getTVType(Html divObj, List<String> pList)
    {
        String type = this.getTVAttr(pList, "类型");
        if (StringUtils.isNotEmpty(type))
            return type;
        type = this.getTVAttr(divObj.xpath("//div[@class='info_it']").all(),
                "类型");
        if (StringUtils.isNotEmpty(type))
            return type;
        String classStr = divObj.xpath("//div[@class='so-result-info']/@class")
                .get();
        if (StringUtils.isNotEmpty(classStr))
        {
            String classTag = RegexUtils
                    .regexSearch("search-movie|search-television", classStr);
            if (StringUtils.isNotEmpty(classTag))
            {
                switch (classTag)
                {
                    case "search-television":
                        return "电视剧";
                    case "search-movie":
                        return "电影";
                    default:
                        break;
                }
            }
        }
        return null;
    }
    
    @Override
    public String getSpiderType()
    {
        return Constants.SpiderTaskType.MGTV_MOVIE_DANMU;
    }

    @Override
    public String getPageDataType(Page page)
    {
        String url = page.getUrl().toString();
        if (url.contains("so.mgtv.com/so/k-"))
            return Constants.PageDataType.SEARCH_LIST;
        else if (url.contains("www.mgtv.com/b"))
        	 return Constants.PageDataType.BASICINFO;
        else if (url.contains("galaxy.bz.mgtv.com/rdbarrage"))
        	return Constants.PageDataType.TV_RECORD;
        return Constants.PageDataType.TV_COMMENT;
    }
    
}
